项目实战--App Recommender System

该项目从华为应用市场爬取 app 数据,存到 MongoDB 中,再经过推荐算法更新数据,展示到前端。项目综合了之前讲到的所有爬虫技巧,来源自 BitTiger 的组织。项目共分为 爬虫模块、推荐模块、网站模块 三部分。

技术需求文档

爬虫模块

http://appstore.huawei.com/more/all 爬取总排行榜所有APP数据

  • Title
  • AppId
  • 缩略图
  • 介绍

http://appstore.huawei.com/topics/ 爬取所有专题
每个专题包括

  • Title
  • AppId List

每个包含在专题中的APP,都爬取

  • Title
  • AppId
  • 缩略图
  • 介绍

http://appstore.huawei.com/ 做为种子,抓取所有App信息

  • App List的信息
  • App 的信息

推荐模块

根据输入的App List,输出与这个List最相关的App List

  • 基础数据:AppId List的集合
  • 输入AppId List
  • 输出AppId List

网站模块

首页 - A List of most popular Apps(类似于AppStore的Top Charts)

  • Title
  • 缩略图
  • 介绍的前20个字符

详情页

  • Title
  • 缩略图
  • 完整介绍
  • 相关推荐的App List

爬虫模块

简介

Skill

  • Python
  • scrapy
  • mongodb
  • proxy
  • scrapyjs

Performance

  • 100 pages/second(vs 30k/second)

爬取

要点:

  1. 利用 Proxy 更换 user-agent
    srcapy 发出请求的 user agent 的默认值为Scrapy/version,和普通浏览器的不同,所以网站就会识别出这不是真的用户而是爬虫,就会屏蔽这些请求。所以我们就使用 proxy 随机模拟了不同的 user agent 来“欺骗”网站,才能成功地爬取页面。这一部分是使用 Scrapy middleware 实现的。
    博客

  2. 利用 scrapy-redis 分布式架构加快爬取速度
    博客

  3. 怎样获取更多数据

    • 通过相似 app
    • 通过搜索
    • 扩展链接

解析

涉及到 ‘下一页’ 的爬取,见爬虫总结-五-其他技巧 使用 scrapy-splash 部分的实例。

存储

文件

appstore.dat 存储基本信息,格式

id \t title \t intro
1
2
3
4
5
C5683 微信 华为手机服务:激活华为会员,立享精彩权益! 更新到手机服务最新版本、免费激活会员,立享高级专属售后服务特权、VIP客服热线,还有160G免费空间、海量衣食住行礼包、华为商城优惠券等你抢! “手机服务”为华为终端用户提供一站式售后服务,集成华为会员、在线寄修、预约维修、在线客服等十多项丰富的在线服务,旨在为亿万华为终端用户提供优质、省心、快捷的服务。 主要
C262 去哪儿旅行 旅游 旅游,去哪儿 去哪儿,酒店 酒店,机票 机票、火车票火车票,门票门票,度假度假,线路线路,快到碗里来! 去哪儿旅行—总有你要的低价! 作为中国领先的无线和在线旅游平台,去哪儿旅行支持用户低价购买近60万条国内国际航线,42万家国内酒店、16万家国际酒店;超100万条国内外度假线路和2万种景点门票;享受国内160座城市,以及国外86座城市的
C10059090 华为游戏中心 华为游戏中心是华为公司提供的安卓游戏下载平台,所有游戏都经过专业的测评团队层层检测,为您推荐最安全质量最高的游戏内容, 目前我们有20万游戏聚众平台,个性化专题定制,和丰富多元的游戏礼包,还有游戏论坛供大家互动,华为游戏中心不单服务所有华为用户,还支持国内主流安卓机型。 新版本特性: 1、新增 资讯频道,最新热点、最强攻略、最全视频,完
C57236 今日头条 今天,看今日头条 今日头条,超过 4 亿用户选择的新闻资讯 App ! 单用户每日使用时长超过60分钟 每天社交平台分享量达550万次 颠覆传统阅读——人“搜索”资讯的模式,运用大数据算法,精准推荐你感兴趣的内容,从此不受冗杂信息困扰,畅游个性化信息海洋,让你的阅读更加有用高效。 【海量内容源】 聚合超过5000
C10217244 华为钱包 华为钱包:1.“红酒”频道,精选莫塞尔多款进口红酒,享受华为特惠价格,让你足不出户品尝世界各地的葡萄佳酿! 2. “钱包”有生活服务、花币中心、红酒等频道,聚合优质服务,提供超值体验。 3. NFC线下支付,集手机支付和线下刷卡为一体,享受安全快捷的支付体验,省去了随身携带钱包、现金和银行卡的麻烦。(NFC支付功能当前支持荣耀V8全网通版、Mate S

appstore_re.dat 存储推荐信息,格式

id \t url \t title \t recommended_appid
1
2
3
4
C5683 http://appstore.huawei.com:80/app/C5683 微信 C2543:QQ同步助手,C9319:QQ,C5373:支付宝,C2682:搜狗输入法,C3466:酷狗音乐,C54626:铃声多多,C2861:同花顺炒股,C36902:WiFi万能钥匙,C104688:腾讯新闻,C21976:UC浏览器,C5683:微信,C9319:QQ,C7166:微博,C10085602:花粉俱乐部,C23563:陌陌,C10154337:易信,C37549:189邮箱,C2543:QQ同步助手,C10405418:QQ邮箱,C19185:百度贴吧,
C262 http://appstore.huawei.com:80/app/C262 去哪儿旅行 C6006:蚂蜂窝自由行,C5157:携程旅行,C30591:途牛旅游,C10770:阿里旅行,C69056:驴妈妈旅游,C10027123:航旅纵横,C12192:同程旅游,C10141560:飞常准,C10017070:高铁管家,C10226376:神州专车,C3382:百度地图,C20911:高德地图,C262:去哪儿旅行,C5157:携程旅行,C10047107:滴滴出行,C5745:天翼导航,C3403:高德导航,C10239309:优步 - Uber,C39196:艺龙旅行,C10043914:和地图,
C10059090 http://appstore.huawei.com:80/app/C10059090 华为游戏中心 C10217244:华为钱包,C10085602:花粉俱乐部,C10173884:天龙八部3D,C10055832:华为文件管理,C10207207:华为云服务,C10049053:华为商城,C10242764:梦幻西游,C27162:华为应用市场,C10126869:刀塔传奇,C66323:华为备份,C36902:WiFi万能钥匙,C27162:华为应用市场,C10055832:华为文件管理,C66323:华为备份,C21976:UC浏览器,C10067631:华为手机服务,C20679:QQ浏览器,C10207207:华为云服务,C10059090:华为游戏中心,C10132067:华为帐号,
C57236 http://appstore.huawei.com:80/app/C57236 今日头条 C19168:凤凰新闻,C9147:网易新闻,C2022:搜狐新闻,C104688:腾讯新闻,C31975:墨迹天气,C40238:内涵段子,C3386:汽车之家,C20960:搜狐视频,C3382:百度地图,C2217:我查查,C57236:今日头条,C9147:网易新闻,C2022:搜狐新闻,C104688:腾讯新闻,C179773:爱读掌阅,C149006:塔读文学,C28837:ZAKER,C86189:爱动漫,C2034:天翼阅读,C10084466:咪咕阅读,

app_info.json 存储 app 所有信息

1
2
{"title": "华为商城", "url": "http://appstore.huawei.com:80/app/C10049053", "app_id": "C10049053", "recommended": "C10085602:花粉俱乐部,C10217244:华为钱包,C10168550:亲情关怀,C10055832:华为文件管理,C10060708:华为支付,C10067631:华为手机服务,C10132067:华为帐号,C10465316:华为众测,C10207207:华为云服务,C66323:华为备份,C34075:手机淘宝,C10049053:华为商城,C5206:美团团购,C10608:大众点评,C57804:天猫,C20252:手机京东,C9136:唯品会,C10116109:百度糯米,C41277:苏宁易购,C10284106:美丽说,", "score": "8", "thumbnail_url": "http://appimg.hicloud.com/hwmarket/files/application/icon144/ea05c760d27f4b58bd6e8b8e88fdc127.png", "intro": "【华为商城客户端 我的掌上购机神器】 预约抢购华为、荣耀新品,华为官方商城,值得信赖!HUAWEI P9、荣耀V8、荣耀畅玩5X、HUAWEI Mate8、荣耀7等众多热门手机及丰富的配件,每月促销活动不断,红包疯狂送,抽奖玩不停! 1、掌上购机神器 每周三移动端专场,手机抢购更便捷; 闹钟提醒,手机抢购不再错过;<b", "developer": "华为终端有限公司"}
{"title": "微博", "url": "http://appstore.huawei.com:80/app/C7166", "app_id": "C7166", "recommended": "C10084137:新浪微博(G3版…,C6056298:VSCO Cam™,C19185:百度贴吧,C10159988:in,C10047082:知乎,C10204517:MIX,C10125085:哔哩哔哩动画,C10318669:PicsArt,C10231827:快看漫画,C10168892:网易云音乐,C5683:微信,C9319:QQ,C7166:微博,C10085602:花粉俱乐部,C23563:陌陌,C10154337:易信,C37549:189邮箱,C2543:QQ同步助手,C10405418:QQ邮箱,C19185:百度贴吧,", "score": "10", "thumbnail_url": "http://appimg.hicloud.com/hwmarket/files/application/icon144/a885314b6da5496084f009a43226dabf.png", "intro": "关于百果园: 百果园,深耕水果行业15年水果连锁品牌,首创水果分级标准。 从2001年百果园创立之日起,信守“一生只做一件事,一心一意做水果”的承诺,15年辛勤耕耘,只为让全天下人享受水果好生活。 目前已经在云南、四川、陕西、山西、山东、江苏、海南等省份以及美国、新西兰等国家建立了100多个水果生产基地,同时配有从果园到门店", "developer": "新浪网技术(中国)有限公司"}

MongoDB

MongoDB 中新建 database appstore,新建 collections user_download_history 和 app_info,导入相应文件。
将文件导入 MongoDB。

$ mongoimport --db appstore --collection user_download_history --drop --file user_download_history.json
$ mongoimport --db appstore --collection app_info --drop --file app_info.json
1
2
3
> db.app_info.find()
{ "_id" : ObjectId("577cbfade677be6b09d8dc2c"), "score" : "8", "title" : "果汁四溅", "url" : "http://appstore.huawei.com:80/app/C10204319", "app_id" : "C10204319", "thumbnail_url" : "http://appimg.hicloud.com/hwmarket/files/application/icon144/f986a241d80d46fcb4fecc1e85121a60.png", "intro" : "【果汁四溅】年度最“溅”的消除游戏!首发大奖10台iphone6溅到你手! ★全球50多个国家APP商店推荐★ ★30个国家桌面游戏排名第一★ ★5000万玩家五星好评★ 游戏特色: 【七大新玩法,酷炫拽!叼咋天!】 【250关挑战极限!救救水果君】 【果汁爆溅,萌翻全场!】 首发", "developer" : "深圳市唯变科技开发有限公司" }
{ "_id" : ObjectId("577cbfade677be6b09d8dc2d"), "score" : "9", "title" : "泡泡龙亚特兰蒂斯", "url" : "http://appstore.huawei.com:80/app/C10145675", "app_id" : "C10145675", "thumbnail_url" : "http://appimg.hicloud.com/hwmarket/files/application/icon144/cb3c6ce12b73424990921097fe20a7b1.png", "intro" : "泡泡龙亚特兰蒂斯:一款令人着迷的泡泡龙游戏。在经典的游戏模式中增加了独有的BOSS战,每个场景都 有独特的守护者等待你的挑战。多种多样的奇趣道具供你使用。打BOSS,秀操作,耍道具让你爱不释手。欢乐之旅由一段美丽的故事带你进入。前所未有的体验,带给你神奇的亚特兰蒂斯之旅。", "developer" : "深圳市灵游科技有限公司" }
1
2
3
> db.user_download_history.find()
{ "_id" : ObjectId("5691f793f0fe47e651ba1a52"), "user_id" : 3, "download_history" : [ "C10249215", "C10221865", "C10269239", "C10157957", "C10148546", "C10241662", "C10203747", "C10144080", "C10136202", "C10271994" ] }
{ "_id" : ObjectId("5691f793f0fe47e651ba1a53"), "user_id" : 4, "download_history" : [ "C10026769", "C10053551", "C10237091", "C10141383", "C10162014", "C10148546" ] }

推荐模块

简介

Skill

  • Python
  • collaborative-filtering algorithm
  • cosine_similarity

Performance

  • 1 second/app(vs with 10ms/app)

推荐算法

协同过滤算法简述

基于用户的协同过滤算法(User CF)

强调 把和你有相似爱好的其他的用户的物品推荐给你
基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。

过程:

  1. 将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到和目标用户兴趣相似的用户集合;
  2. 找到这个集合中的用户喜欢的,且目标用户没有访问过的物品,计算得到一个排序的物品列表作为推荐。

优点和适用场景:

  • 可以发现用户感兴趣的热门物品
  • 用户有新行为,不一定造成推荐结果的立即变化
  • 适用于用户较少的场合,否则用户相似度矩阵计算代价很大
  • 适合时效性较强,用户个性化兴趣不太明显的领域

缺点:

  • 数据稀疏性。一个大型的电子商务推荐系统一般有非常多的物品,用户可能买的其中不到1%的物品,不同用户之间买的物品重叠性较低,导致算法无法找到一个用户的邻居,即偏好相似的用户。
  • 算法扩展性。最近邻居算法的计算量随着用户和物品数量的增加而增加,不适合数据量大的情况使用。
  • 对新用户不友好,对新物品友好,因为用户相似度矩阵不能实时计算
  • 很难提供令用户信服的推荐解释

基于物品的协同过滤算法

强调 把和你喜欢的物品相似的物品推荐给你
基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度。在京东、天猫上看到「购买了该商品的用户也经常购买的其他商品」,就是主要基于 ItemBasedCF。

过程:

  1. 基于用户对物品的偏好计算相似度,找到相似的物品;
  2. 根据物品的相似度和用户的历史行为预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。

因为物品直接的相似性相对比较固定,所以可以预先在线下计算好不同物品之间的相似度,把结果存在表中,当推荐时进行查表,计算用户可能的打分值。

优点和适用场景:

  • 可以发现用户潜在的但自己尚未发现的兴趣爱好
  • 有效的进行长尾挖掘
  • 利用用户的历史行为给用户做推荐解释,使用户比较信服
  • 适用于物品数明显小于用户数的场合,否则物品相似度矩阵计算代价很大
  • 适合长尾物品丰富,用户个性化需求强的领域

缺点:

  • 对新用户友好,对新物品不友好,因为物品相似度矩阵不需要很强的实时性

Item CF 和 User CF 是基于协同过滤推荐的两个最基本的算法,大家都觉得 Item CF 从性能和复杂度上比 User CF 更优,其中的一个主要原因就是对于一个在线网站,用户的数量往往大大超过物品的数量,同时物品的数据相对稳定,因此计算物品的相似度不但计算量较小,但这种情况只适应于提供商品的电子商务网站,对于新闻,博客或者微内容的推荐系统,情况往往是相反的,物品的数量是海量的,同时也是更新频繁的,所以单从复杂度的角度,这两个算法在不同的系统中各有优势,推荐引擎的设计者需要根据自己应用的特点选择更加合适的算法。

两个例子:

非社交网络:在非社交网络的网站中,内容内在的联系是很重要的推荐原则,它比基于相似用户的推荐原则更加有效。比如在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关的书籍,这个推荐的重要性远远超过了网站首页对该用户的综合推荐。可以看到,在这种情况下,Item CF 的推荐成为了引导用户浏览的重要手段。同时 Item CF 便于为推荐做出解释,在一个非社交网络的网站中,给某个用户推荐一本书,因为这本书和你以前看的某本书相似,用户可能就觉得合理而采纳了此推荐。

社交网络:在现今很流行的社交网络站点中,User CF 是一个更不错的选择,User CF 加上社会网络信息,可以增加用户对推荐解释的信服程度。

更多见[推荐算法]基于用户的协同过滤算法

项目算法

采用的是基于物品的协同过滤算法,相似度算法用的是 cosine similarity。通过计算 similarity between a1 and all user download history 来推导 similarity between a1 and all other apps,前提是假定每个 user download history list 里的 app 是相互关联的。看下面的具体例子。

cosine similarity

similarity between a3 and a5

a3’s top-5 related apps

实现

首先读取 MongoDB 的数据,过程略。这里主要展示算法实现。
cosine similarity

1
2
3
4
5
6
7
8
9
10
11
12
@classmethod
def cosine_similarity(cls, app_list1, app_list2):
match_count = cls.__count_match(app_list1, app_list2)
return float(match_count) / math.sqrt( len(app_list1) * len(app_list2))
@classmethod
def __count_match(cls, list1, list2):
count = 0
for element in list1:
if element in list2:
count += 1
return count

top-5 related app_list1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def calculate_top_5(app, user_download_history):
'''
cosine_similarity between an App and user's history
'''
#create a dict to store each other app and its similarity to this app
app_similarity = collections.defaultdict(float) #{app_id: similarity}
for apps in user_download_history:
#calculate the similarity
similarity = Helper.cosine_similarity([app], apps)
# accumluate similarity
for other_app in apps:
app_similarity[other_app] += similarity
# There could be app without related apps (not in any download history)
if not app in app_similarity:
return
#sort app_similarity dict by value and get the top 5 as recommendation
app_similarity.pop(app)
sorted_tups = sorted(app_similarity.items(), key=operator.itemgetter(1), reverse=True)#sort by similarity
top_5_app = [sorted_tups[0][0], sorted_tups[1][0], sorted_tups[2][0], sorted_tups[3][0], sorted_tups[4][0]]
#print("top_5_app for " + str(app) + ":\t" + str(top_5_app))

最后要更新 MongoDB 中的数据。更新后的数据如下

1
2
{ "_id" : ObjectId("577cbfade677be6b09d8dc2c"), "score" : "8", "title" : "果汁四溅", "url" : "http://appstore.huawei.com:80/app/C10204319", "app_id" : "C10204319", "thumbnail_url" : "http://appimg.hicloud.com/hwmarket/files/application/icon144/f986a241d80d46fcb4fecc1e85121a60.png", "intro" : "【果汁四溅】年度最“溅”的消除游戏!首发大奖10台iphone6溅到你手! ★全球50多个国家APP商店推荐★ ★30个国家桌面游戏排名第一★ ★5000万玩家五星好评★ 游戏特色: 【七大新玩法,酷炫拽!叼咋天!】 【250关挑战极限!救救水果君】 【果汁爆溅,萌翻全场!】 首发", "developer" : "深圳市唯变科技开发有限公司", "top_5_app" : [ "C10053551", "C10148546", "C10141383", "C10189589", "C10026769" ] }
{ "_id" : ObjectId("577cbfade677be6b09d8dc2d"), "score" : "9", "title" : "泡泡龙亚特兰蒂斯", "url" : "http://appstore.huawei.com:80/app/C10145675", "app_id" : "C10145675", "thumbnail_url" : "http://appimg.hicloud.com/hwmarket/files/application/icon144/cb3c6ce12b73424990921097fe20a7b1.png", "intro" : "泡泡龙亚特兰蒂斯:一款令人着迷的泡泡龙游戏。在经典的游戏模式中增加了独有的BOSS战,每个场景都 有独特的守护者等待你的挑战。多种多样的奇趣道具供你使用。打BOSS,秀操作,耍道具让你爱不释手。欢乐之旅由一段美丽的故事带你进入。前所未有的体验,带给你神奇的亚特兰蒂斯之旅。", "developer" : "深圳市灵游科技有限公司", "top_5_app" : [ "C2217", "C40224", "C10196888", "C10197446", "C10047107" ] }

网站模块

Skill

  • javascript
  • node.js
  • meteor
  • mongodb

Performance

  • 1k QPS (vs 10k QPS)

具体实现见 Meteor – App Recommender System

徐阿衡 wechat
欢迎关注:徐阿衡的微信公众号
客官,打个赏呗~